#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>



#include "network.h"


#define BUFF_SIZE 1024
#define PORT_NUM 4002


void Network::init()
{
	struct sockaddr_in serverAddr;

	serverSocket = socket(PF_INET, SOCK_STREAM, 0);
	if( serverSocket == -1 )
	{
		printf("socket() fail\n");
		exit(1);
	}

	memset(&serverAddr, 0, sizeof( serverAddr));
	serverAddr.sin_family = AF_INET;
	serverAddr.sin_port = htons( PORT_NUM );
	serverAddr.sin_addr.s_addr = htonl( INADDR_ANY );

	if ( bind( serverSocket, (struct sockaddr*)&serverAddr, sizeof(serverAddr)) == -1 )
	{
		printf("bind() fail\n");
		exit(1);
	}
	
	if( listen(serverSocket, 5) == -1 )
	{
		printf("listen() fail\n");
		exit(1);
	}

}

string Network::recvFromCli()
{
	string retv;





	return retv;
}

void Network::sendToCli(string str)
{
	pthread_mutex_lock(&cliSocketMutexLock);

	int numOfClientSocketVector = clientSocketVector.size();

	pthread_mutex_unlock(&cliSocketMutexLock);

	if(numOfClientSocketVector == 0)
		return;
	vector<int> index;
	int numOfStr = str.size();
	int numOfSendLine = (numOfStr / 1024) + 1;
	
	for(int i = 0; i < numOfClientSocketVector; i++)
	{

		for( int j = 0; j < numOfSendLine; j++)
		{
			if( send(clientSocketVector[i], str.c_str() + 1024*j, ( j == (numOfSendLine - 1)) ?  numOfStr-1024*j : 1024, 0) == -1)
			{
				index.push_back(i);
				break;
			}
		}
	}
	
	if( !index.empty() )
	{
		pthread_mutex_lock(&cliSocketMutexLock);
		int numOfEraseIndex = index.size();

		for(int i = 0; i < numOfEraseIndex; i++)
		{
			clientSocketVector.erase(clientSocketVector.begin() + index[numOfEraseIndex-i-1]);
		}
	
		pthread_mutex_unlock(&cliSocketMutexLock);
	}
}

void Network::cleanup()
{
}

void Network::acceptFromCli()
{
	int clientSocket;
	socklen_t clientAddrSize;
	struct sockaddr_in clientAddr;

	clientAddrSize = sizeof(clientAddr);
	while(1)
	{

		clientSocket = accept( serverSocket, (struct sockaddr*)&clientAddr, &clientAddrSize);
		
		if( clientSocket == -1)
			printf("accept() fail\n");
		else
		{
			pthread_mutex_lock(&cliSocketMutexLock);
			clientSocketVector.push_back(clientSocket);
			pthread_mutex_unlock(&cliSocketMutexLock);
		}
	}
}
